<?php

namespace App\Models\Traits;

use Carbon\Carbon;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Validation\ValidationException;
use Illuminate\Database\Eloquent\Relations\HasMany;

trait HasUserTeam
{
	public function myDownOneChildren($scope = null, $keyword = ''): HasMany
	{
		$children = $this->children();
		if ($scope === 'normal') {
			$children = $children->where('grade', '<>', 'vip');
		}
		if ($scope === 'vip') {
			$children = $children->where('grade', 'vip')->where('is_gold_intern', false)->where('is_gold_master', false);
		}
		if ($scope === 'gvip') {
			$children = $children->where('grade', 'vip')->where('is_gold_intern', true)->where('is_gold_master', true);
		}
		if ($keyword) {
			$children = $children->where(function (Builder $query) use ($keyword) {
				$query->where('id', $keyword)
					->orWhere('phone', $keyword)
					->orWhere('name', 'like', "%{$keyword}%")
					->orWhere('nickname', 'like', "%{$keyword}%");
			});
		}

		return $children;
	}

	public function myDownOneChildrenWithRecord($scope = null, $keyword = '')
	{
		$children = User::query()
				->withCount(['goldRecords as today_record_count' =>function($query){
						$query->where('created_at', '>' ,Carbon::today()->toDateString())->where('paid_at', '>' ,Carbon::today()->toDateString());

				}])
				->withCount(['goldRecords as today_record_price' =>function($query){
						$query->select(DB::raw("sum(pay_net_price) as today_record_price"))->where('created_at', '>', Carbon::today()->toDateString())->where('paid_at', '>' ,Carbon::today()->toDateString());

				}])
				->where(function (Builder $query) use ($keyword) {
					$query->where('id', $this->id)
						->orWhere('parent_id', $this->id);
					});


		if ($scope === 'vip') {
			$children = $children->where('grade', 'vip')->where('is_gold_master', 0)->where('is_gold_intern', 0);
		}

		if ($scope === 'master') {
			$children = $children->where('grade', 'vip')->where('is_gold_master', 1);
		}

		if ($scope === 'intern') {
			$children = $children->where('grade', 'vip')->where('is_gold_intern', 1)->where('is_gold_master', 0);
		}

		if ($keyword) {
			$children = $children->where(function (Builder $query) use ($keyword) {
				$query->where('id', $keyword)
					->orWhere('phone', $keyword)
					->orWhere('invite_code', $keyword)
					->orWhere('name', 'like', "%{$keyword}%")
					->orWhere('nickname', 'like', "%{$keyword}%");
			});
		}

		return $children;
	}

	public function myValidGoldStormChildren()
	{
		return $this->children()
			->where('grade', 'vip')
			->where('is_locked', false)
			->whereHas('goldRecords', function (Builder $query) {
				$query->whereNotNull('paid_at');
			});
	}

	public function needValidGoldStormChildrenForUpgrade()
	{
		$requiredChildren = sc('each_upgrade_needs_children');
		$needChildren = $requiredChildren - $this->myValidGoldStormChildren()->count();
		return $needChildren > 0 ? $needChildren : $requiredChildren;
	}

	public function myTargetGoldPrizeParents()
	{
		$parents = collect();
		$currentUser = $this->parent;
		$demandPrizeParentsAmount = (int)cs('storm')->child_record_give_team_parent_masters_amount;

		if ($demandPrizeParentsAmount <= 0) return $parents;

		while (true) {
			if (!$currentUser or $parents->count() >= $demandPrizeParentsAmount) {
				break;
			}
			if ($currentUser->isValidGoldMaster()
				and $currentUser->hasValidGoldRecord()) {
				$parents->push($currentUser);
			}
			$currentUser = $currentUser->parent;
		}
		return $parents;
	}

	public function setChildNickname(User $user)
	{
		if (!$user->parent or $user->parent->id !== $this->id) {
			fail('仅可备注属于自己团队成员');
		}
	    request()->validate(['nickname' => 'nullable|string|min:1|max:20']);
		$user->update(['nickname' => request('nickname')]);
	}

	public function dayBonusTop100()
	{
		return self::query()
			->select('id')
			->where('grade', 'vip')
			->where('is_locked', false)
			->where('dividend_day', '>', 0)
			->orderByDesc('dividend_day')
			->orderBy('id')->take(100)
			->get()->pluck('id');
	}

	public function allBonusTop100()
	{
		return self::query()
			->select('id')
			->where('grade', 'vip')
			->where('is_locked', false)
			->where('dividend_all', '>', 0)
			->orderByDesc('dividend_all')
			->orderBy('id')->take(100)
			->get()->pluck('id');
	}
}
